﻿package com.agileai.miscdp.hotweb.ui.editors.mastersub;

import java.io.File;
import java.io.StringWriter;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;

import com.agileai.miscdp.hotweb.database.DBManager;
import com.agileai.miscdp.hotweb.domain.BaseFuncModel;
import com.agileai.miscdp.hotweb.domain.ListTabColumn;
import com.agileai.miscdp.hotweb.domain.PageFormField;
import com.agileai.miscdp.hotweb.domain.PageParameter;
import com.agileai.miscdp.hotweb.domain.mastersub.MasterSubFuncModel;
import com.agileai.miscdp.hotweb.domain.mastersub.SubTableConfig;
import com.agileai.miscdp.hotweb.ui.editors.BaseModelEditor;
import com.agileai.miscdp.hotweb.ui.views.TreeObject;
import com.agileai.miscdp.util.DialogUtil;
import com.agileai.miscdp.util.MiscdpUtil;
import com.agileai.hotweb.model.EditTableType;
import com.agileai.hotweb.model.ListTableType;
import com.agileai.hotweb.model.QueryBarType;
import com.agileai.hotweb.model.mastersub.MasterSubFuncModelDocument;
import com.agileai.hotweb.model.mastersub.MasterSubFuncModelDocument.MasterSubFuncModel.BaseInfo.SubTableInfo;
import com.agileai.hotweb.model.mastersub.MasterSubFuncModelDocument.MasterSubFuncModel.BaseInfo.Template.Enum;
import com.agileai.hotweb.model.mastersub.MasterSubFuncModelDocument.MasterSubFuncModel.EditMainView.SubEntryEditArea;
import com.agileai.hotweb.model.mastersub.MasterSubFuncModelDocument.MasterSubFuncModel.EditMainView.SubListViewArea;
import com.agileai.util.FileUtil;
import com.agileai.util.ListUtil;
import com.agileai.util.StringUtil;
/**
 * 主从表操作功能模型编辑器
 */
public class MasterSubModelEditor extends BaseModelEditor{
	private MSBasicConfigPage sMBasicConfigPage;
	private MSListJspCfgPage sMListJspCfgPage;
	private MSDetailJspCfgPage sMDetailJspCfgPage;
	
    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
        setSite(site);
        setInput(input);
        setPartName(input.getName());
		init();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
    }
	private void init() {
		funcModel = (MasterSubFuncModel)this.getEditorInput();
	}

	protected void createPages() {
		sMBasicConfigPage = new MSBasicConfigPage(getContainer(),this,SWT.NONE);
		sMListJspCfgPage = new MSListJspCfgPage(getContainer(),this,SWT.NONE);
		sMDetailJspCfgPage = new MSDetailJspCfgPage(getContainer(),this,SWT.NONE);
		
		String basicConfig = MiscdpUtil.getIniReader().getValue("EditorInfo","BasicInfo");
		int basicConfigIndex = addPage(sMBasicConfigPage);
		setPageText(basicConfigIndex,basicConfig);
		sMBasicConfigPage.createContent();
		
		String listJspConfig = MiscdpUtil.getIniReader().getValue("EditorInfo","ListInfo");
		int listJspCfgIndex = addPage(sMListJspCfgPage);
		setPageText(listJspCfgIndex,listJspConfig);
		sMListJspCfgPage.createContent();
		
		String detailJspConfig = MiscdpUtil.getIniReader().getValue("EditorInfo","DetailInfo");
		int detailJspCfgIndex = addPage(sMDetailJspCfgPage);
		setPageText(detailJspCfgIndex, detailJspConfig);
		sMDetailJspCfgPage.createContent();
		
		initValues();
		
		sMBasicConfigPage.registryModifier();
		sMListJspCfgPage.registryModifier();
		sMDetailJspCfgPage.registryModifier();
	}
	public void doSave(IProgressMonitor monitor) {
		try {
			MasterSubFuncModel suFuncModel = buildFuncModel();
	    	String projectName = suFuncModel.getProjectName();
	    	IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
	    	
	    	String sql = sMBasicConfigPage.getListSqlText().getText();
	    	if (StringUtil.isNullOrEmpty(sql)){
	    		String sqlCheckNullMsg = MiscdpUtil.getIniReader().getValue("MasterSubModelEditor","SqlCheckNullMsg");
	    		DialogUtil.showInfoMessage(sqlCheckNullMsg);
	    		return;
	    	}
	    	String template = sMBasicConfigPage.getsMExtendAttribute().getTemplateCombo().getText();
	    	if (StringUtil.isNullOrEmpty(template)){
	    		DialogUtil.showInfoMessage("模板不能为空，请选择！");
	    		return;
	    	}

	    	String abstSqlMapPath = project.getLocation().toString()+"/src/sqlmap";
	    	File tempFile = new File(abstSqlMapPath);
	    	if (!tempFile.exists()){
	    		tempFile.mkdirs();
	    	}
	    	
	    	MasterSubFuncModelDocument funcModelDocument = (MasterSubFuncModelDocument)buildFuncModelDocument(suFuncModel);
	    	if (funcModelDocument == null){
	    		return;
	    	}
			StringWriter writer = new StringWriter();
			funcModelDocument.save(writer);
			String funcName = suFuncModel.getFuncName();
			String funcSubPkg = suFuncModel.getFuncSubPkg();
			
			String funcDefine = writer.toString();
			String funcId = suFuncModel.getFuncId();
			String fileName = MiscdpUtil.getFuncFileName(projectName,funcId);
			FileUtil.writeFile(fileName, funcDefine);
			
			this.isModified = false;
			firePropertyChange(PROP_DIRTY);
			
			TreeViewer funcTreeViewer = funcModelTree.getFuncTreeViewer();
			ISelection selection = funcTreeViewer.getSelection();
			Object obj = ((IStructuredSelection) selection).getFirstElement();
			TreeObject treeObject = null;
			if (obj instanceof TreeObject) {
				treeObject = (TreeObject) obj;
				treeObject.setName(funcName);
				treeObject.setFuncSubPkg(funcSubPkg);
			}

			updateIndexFile(projectName);
			
			this.setPartName(funcName);
			funcTreeViewer.refresh();
			try {
				suFuncModel.buildFuncModel(funcDefine);
				project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
			} catch (CoreException e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public MSBasicConfigPage getBasicConfigPage() {
		return sMBasicConfigPage;
	}
	public MSListJspCfgPage getListJspCfgPage() {
		return sMListJspCfgPage;
	}
	public MSDetailJspCfgPage getDetailJspCfgPage() {
		return sMDetailJspCfgPage;
	}
	public MasterSubFuncModel buildFuncModel() {
		this.sMBasicConfigPage.buildConfig();
		this.sMListJspCfgPage.buildConfig();
		return this.sMDetailJspCfgPage.buildConfig();
	}
	public void initValues() {
		this.sMBasicConfigPage.initValues();
		this.sMListJspCfgPage.initValues();
		this.sMDetailJspCfgPage.initValues();
	}
	public MasterSubFuncModel getFuncModel() {
		return (MasterSubFuncModel)funcModel;
	}
	@SuppressWarnings("unchecked")
	public Object buildFuncModelDocument(BaseFuncModel baseFuncModel){
		MasterSubFuncModel msFuncModel = (MasterSubFuncModel)baseFuncModel;
		MasterSubFuncModelDocument funcModelDocument = MasterSubFuncModelDocument.Factory.newInstance();
		MasterSubFuncModelDocument.MasterSubFuncModel funcModel = funcModelDocument.addNewMasterSubFuncModel();
		MasterSubFuncModelDocument.MasterSubFuncModel.BaseInfo baseInfo = funcModel.addNewBaseInfo();
		String tableName = msFuncModel.getTableName();
		String detailJspName = msFuncModel.getDetailJspName();
		String listJspName = msFuncModel.getListJspName();
		baseInfo.setDetailJspName(detailJspName);
		baseInfo.setDetailTitle(msFuncModel.getDetailTitle());
		baseInfo.setTemplate(Enum.forString(msFuncModel.getTemplate()));
		baseInfo.setListJspName(listJspName);
		baseInfo.setListTitle(msFuncModel.getListTitle());
		baseInfo.setQueryListSql(msFuncModel.getListSql());
		baseInfo.setTableName(tableName);
		if (StringUtil.isNullOrEmpty(msFuncModel.getTablePK())){
			String projectName = msFuncModel.getProjectName();
			DBManager dbManager = DBManager.getInstance(projectName);
			String[] primaryKeys = dbManager.getPrimaryKeys(tableName);
			msFuncModel.setTablePK(primaryKeys[0]);
		}
		baseInfo.setTablePK(msFuncModel.getTablePK());
		
		List<SubTableConfig> subTableConfigList = msFuncModel.getSubTableConfigs();
		if (MasterSubFuncModel.TEMPLATE_BASETABED.equals(msFuncModel.getTemplate())){
			baseInfo.setDefaultTabId(MasterSubFuncModel.BAS_TAB_ID);
		}else{
			baseInfo.setDefaultTabId(subTableConfigList.get(0).getSubTableId());	
		}
		
		MasterSubFuncModelDocument.MasterSubFuncModel.BaseInfo.Service service = baseInfo.addNewService();
		String interfaceName = msFuncModel.getInterfaceName();
		service.setServiceId(msFuncModel.getServiceId());
		service.setImplClassName(msFuncModel.getImplClassName());
		service.setInterfaceName(interfaceName);
		
		String editHandlerId = detailJspName.substring(0,detailJspName.length()-4);
		editHandlerId = editHandlerId.substring(editHandlerId.lastIndexOf("/")+1,editHandlerId.length());
		String listHandlerId = listJspName.substring(0,listJspName.length()-4);
		listHandlerId = listHandlerId.substring(listHandlerId.lastIndexOf("/")+1,listHandlerId.length());
		String tempClassPath = interfaceName.substring(0,interfaceName.lastIndexOf(".")).replace("bizmoduler","controller"); 
		String listHandlerClass = tempClassPath + "." + listHandlerId + "Handler";
		String editHandlerClass = tempClassPath + "." + editHandlerId + "Handler";
		MasterSubFuncModelDocument.MasterSubFuncModel.BaseInfo.Handler handler = baseInfo.addNewHandler();
		handler.setEditHandlerId(editHandlerId);
		handler.setEditHandlerClass(editHandlerClass);
		handler.setListHandlerId(listHandlerId);
		handler.setListHandlerClass(listHandlerClass);
		
		MasterSubFuncModelDocument.MasterSubFuncModel.BaseInfo.SqlResource sqlResource = baseInfo.addNewSqlResource();
		
		sqlResource.setSqlNameSpace(tableName.toLowerCase());
		String sqlMapPath = "sqlmap/"+tableName+".xml";;
		sqlResource.setSqlMapPath(sqlMapPath);
		
		baseInfo.setQueryListSql(msFuncModel.getListSql());
		
		String projectName = msFuncModel.getProjectName();
		
		for (int i=0;i < subTableConfigList.size();i++){
			SubTableConfig subTableConfig = subTableConfigList.get(i);
			SubTableInfo subTableInfo = baseInfo.addNewSubTableInfo();
			String subTableName = subTableConfig.getTableName();
			subTableInfo.setTableName(subTableName);
			subTableInfo.setEditMode(MasterSubFuncModelDocument.MasterSubFuncModel.BaseInfo.SubTableInfo.EditMode.Enum.forString(subTableConfig.getEditMode()));
			subTableInfo.setForeignKey(subTableConfig.getForeignKey());
			subTableInfo.setSortField(subTableConfig.getSortField());
			subTableInfo.setQueryListSql(subTableConfig.getQueryListSql());
			subTableInfo.setTabName(subTableConfig.getTabTitile());
			subTableInfo.setSubTableId(subTableConfig.getSubTableId());
			if (StringUtil.isNullOrEmpty(subTableConfig.getPrimaryKey())){
				DBManager dbManager = DBManager.getInstance(projectName);
				String[] primaryKeys = dbManager.getPrimaryKeys(subTableName);
				subTableConfig.setPrimaryKey(primaryKeys[0]);
			}
			subTableInfo.setPrimaryKey(subTableConfig.getPrimaryKey());
		}
		
		MasterSubFuncModelDocument.MasterSubFuncModel.ListView listView = funcModel.addNewListView();
		List<PageParameter> pageParameters = msFuncModel.getPageParameters();
		QueryBarType queryBarType = listView.addNewParameterArea(); 
		this.processQueryBarType(queryBarType, pageParameters);
		
		ListTableType listTableType = listView.addNewListTableArea();
		listTableType.setExportCsv(msFuncModel.isExportCsv());
		listTableType.setExportXls(msFuncModel.isExportXls());
		listTableType.setPagination(msFuncModel.isPagination());
		listTableType.setSortAble(msFuncModel.isSortAble());
		
		List<ListTabColumn> listTabColumns = msFuncModel.getListTableColumns();
		if (msFuncModel.getRsIdColumns().isEmpty()){
			DBManager dbManager = DBManager.getInstance(projectName);
			String[] primaryKeys = dbManager.getPrimaryKeys(tableName);
			msFuncModel.getRsIdColumns().addAll(ListUtil.arrayToList(primaryKeys));
		}
		String rsIdColumn = StringUtils.join(msFuncModel.getRsIdColumns().toArray(),",");
		this.processListTableType(listTableType, listTabColumns, rsIdColumn);
		
		MasterSubFuncModelDocument.MasterSubFuncModel.EditMainView editMainView = funcModel.addNewEditMainView();
		EditTableType editTableType = editMainView.addNewMasterEditArea();
		List<PageFormField> pageFormFields = msFuncModel.getPageFormFields();
		this.processEditTableType(editTableType, pageFormFields);
		
		for (int i = 0;i < msFuncModel.getSubTableConfigs().size();i++){
			SubTableConfig subTableConfig = msFuncModel.getSubTableConfigs().get(i);
			String subTableId = subTableConfig.getSubTableId();
			String editMode = subTableConfig.getEditMode();
			String primaryKey = subTableConfig.getPrimaryKey();
			String sortField = subTableConfig.getSortField();
			if (SubTableConfig.ENTRY_EDIT_MODE.equals(editMode)){
				List<PageFormField> subParamField = msFuncModel.getSubEntryEditFormFields(subTableId);
				SubEntryEditArea subEntryEditArea = editMainView.addNewSubEntryEditArea();
				subEntryEditArea.setTabName(subTableConfig.getTabTitile());
				subEntryEditArea.setSubTableId(subTableId);
				subEntryEditArea.setSortField(sortField);
				if (subParamField!= null){
					this.processEditTableType(subEntryEditArea, subParamField);	
				}
			}
			else if (SubTableConfig.LIST_DETAIL_MODE.equals(editMode)){
				List<ListTabColumn> listTableColumms = msFuncModel.getSubListTableColumns(subTableId);
				SubListViewArea subListViewArea = editMainView.addNewSubListViewArea();
				subListViewArea.setTabName(subTableConfig.getTabTitile());
				subListViewArea.setSubTableId(subTableId);
				subListViewArea.setSortField(sortField);
				subListViewArea.setHandlerId(subTableConfig.getPboxHandlerId());
				subListViewArea.setPrimaryKey(primaryKey);
				if (listTableColumms != null){
					this.processListTableType(subListViewArea,listTableColumms,primaryKey);					
				}
				
				MasterSubFuncModelDocument.MasterSubFuncModel.EditPboxView editBoxView = funcModel.addNewEditPboxView();
				EditTableType boxEditTableType = editBoxView.addNewSubPboxEditArea();
				editBoxView.setSubTableId(subTableId);
				String pboxJspName = subTableConfig.getPboxJspName();
				if (StringUtil.isNullOrEmpty(pboxJspName)){
					DialogUtil.showInfoMessage("操作出错，请尝试重新初始化！");
					return null;
				}
				editBoxView.setJspName(subTableConfig.getPboxJspName());
				String pboxHandlerId = pboxJspName.substring(0,pboxJspName.length()-4);
				pboxHandlerId = pboxHandlerId.substring(pboxHandlerId.lastIndexOf("/")+1,pboxHandlerId.length());
				String pboxTempClassPath = interfaceName.substring(0,interfaceName.lastIndexOf(".")).replace("bizmoduler","controller"); 
				String pboxHandlerClass = pboxTempClassPath + "." + pboxHandlerId + "Handler";
				editBoxView.setHandlerId(pboxHandlerId);
				editBoxView.setHandlerClass(pboxHandlerClass);
				
				List<PageFormField> boxFormFields = msFuncModel.getSubPboxFormFields(subTableId);
				this.processEditTableType(boxEditTableType, boxFormFields);
			}
		}
		return funcModelDocument;
	}
}
